<!DOCTYPE html>
<html lang="en">
  <head>
    
      <title>django&#43;redis的排行榜 :: Rennan Blog — We can exchange and study together</title>
    
    <meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1">
<meta name="description" content="利用了redis中的有序集合 可以将添加进来的key:value形式的数据 根据value来进行排序 value得是int
import redishost = &#39;127.0.0.1&#39;port = 6379r = redis.Redis(host=host,port=port)r.zadd(&#39;z&#39;,{&#39;冰箱&#39;:20})r.zadd(&#39;z&#39;,{&#39;手机&#39;:30})print(r.zrange(&#39;m&#39;,0,10,desc=True,withscores=True)) #desc=True 倒序 创建好接口后直接用zincrby()方法来将其中的某个元素进行相应的操作 zincrby(&amp;lsquo;有序集合&amp;rsquo;,增减数量,增减的key)
class GoodsClick(APIView):def get(self,request):# 接收参数gid = request.GET.get(&#39;gid&#39;,None)# 修改商品点击数r.zincrby(&amp;quot;good_rank&amp;quot;,1,int(gid))return Response({&amp;quot;message&amp;quot;:&amp;quot;访问了&amp;quot;}) 可以构造一个通用可以复用的方法 方法内部实现了对数据的进一步封装 {商品点击量：商品}
# 获取n名数据def get_top_n(num):# 获取redis排行榜goods_click = r.zrange(&#39;good_rank&#39;,0,-1,desc=True,withscores=True)[:num]goods = Goods.objects.in_bulk([int(item[0]) for item in goods_click])res = []for item in goods_click:res.append({int(item[1]):goods[int(item[0])]})return res 构建一个返回排行榜数据的接口 其中将上面的方法进行调用 方法返回这个接口需要的数据 之后将返回的数据进行序列化 并将商品的点击数添加到序列化数据中"/>
<meta name="keywords" content=""/>
<meta name="robots" content="noodp"/>
<link rel="canonical" href="/my_blog/post/three/" />





<link rel="stylesheet" href="/my_blog/assets/style.css">


<link rel="stylesheet" href="/my_blog/style.css">


<link rel="apple-touch-icon-precomposed" sizes="144x144" href="/my_blog/img/apple-touch-icon-144-precomposed.png">
<link rel="shortcut icon" href="/my_blog/img/favicon.png">


<meta name="twitter:card" content="summary"/>
<meta name="twitter:title" content="django&#43;redis的排行榜"/>
<meta name="twitter:description" content="django&#43;redis实现排行榜"/>



<meta property="og:title" content="django&#43;redis的排行榜" />
<meta property="og:description" content="django&#43;redis实现排行榜" />
<meta property="og:type" content="article" />
<meta property="og:url" content="/my_blog/post/three/" />
<meta property="article:published_time" content="2020-04-07T14:38:53+10:00" />
<meta property="article:modified_time" content="2020-04-07T14:38:53+10:00" /><meta property="og:site_name" content="Rennan Blog" />






  </head>
  <body class="">
    <div class="container">
      <header class="header">
  <span class="header__inner">
    <a href="/my_blog/hello/" class="logo" style="text-decoration: none;">
  
    <span class="logo__mark"><svg xmlns="http://www.w3.org/2000/svg" class="greater-icon" viewBox="0 0 44 44">
  <path fill="none" d="M15 8l14.729 14.382L15 35.367"/>
</svg>
</span>
    <span class="logo__text">Welcome To MyBlog</span>
    <span class="logo__cursor"></span>
  
</a>

    <span class="header__right">
      
        <nav class="menu">
  <ul class="menu__inner menu__inner--desktop">
    
      
        
          <li><a href="/my_blog/resume">resume</a></li>
        
      
        
          <li><a href="/my_blog/vue">vue</a></li>
        
      
      
    
  </ul>

  <ul class="menu__inner menu__inner--mobile">
    
      
        <li><a href="/my_blog/resume">resume</a></li>
      
    
      
        <li><a href="/my_blog/vue">vue</a></li>
      
    
  </ul>
</nav>

        <span class="menu-trigger">
          <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
            <path d="M0 0h24v24H0z" fill="none"/>
            <path d="M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z"/>
          </svg>
        </span>
      
      <span class="theme-toggle">
        <svg class="theme-toggler" width="24" height="24" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
  <path d="M22 41C32.4934 41 41 32.4934 41 22C41 11.5066 32.4934 3 22
  3C11.5066 3 3 11.5066 3 22C3 32.4934 11.5066 41 22 41ZM7 22C7
  13.7157 13.7157 7 22 7V37C13.7157 37 7 30.2843 7 22Z"/>
</svg>

      </span>
    </span>
  </span>
</header>


      <div class="content">
        
  
  

  <div class="post">
    <h2 class="post-title"><a href="/my_blog/post/three/">django+redis的排行榜</a></h2>
    <div class="post-meta">
      
        <span class="post-date">
          7046-08-07
        </span>

        
          
        
      

      <span class="post-author">— Written by ren nan</span>
      
    </div>

    

    

    <div class="post-content">
      <p><strong>利用了redis中的有序集合</strong>
可以将添加进来的key:value形式的数据  根据value来进行排序 value得是int</p>
<pre><code>import redis

host = '127.0.0.1'
port = 6379

r = redis.Redis(host=host,port=port)

r.zadd('z',{'冰箱':20})
r.zadd('z',{'手机':30})

print(r.zrange('m',0,10,desc=True,withscores=True))  #desc=True 倒序

</code></pre><hr>
<p>创建好接口后直接用zincrby()方法来将其中的某个元素进行相应的操作
zincrby(&lsquo;有序集合&rsquo;,增减数量,增减的key)</p>
<pre><code>class GoodsClick(APIView):

    def get(self,request):
        # 接收参数
        gid = request.GET.get('gid',None)

        # 修改商品点击数
        r.zincrby(&quot;good_rank&quot;,1,int(gid))

        return Response({&quot;message&quot;:&quot;访问了&quot;})

</code></pre><hr>
<p>可以构造一个通用可以复用的方法
方法内部实现了对数据的进一步封装
{商品点击量：商品}</p>
<pre><code># 获取n名数据
def get_top_n(num):

    # 获取redis排行榜
    goods_click = r.zrange('good_rank',0,-1,desc=True,withscores=True)[:num]

    goods = Goods.objects.in_bulk([int(item[0]) for item in goods_click])

    res = []
    for item in goods_click:
        res.append({int(item[1]):goods[int(item[0])]})

    return res
</code></pre><hr>
<p>构建一个返回排行榜数据的接口
其中将上面的方法进行调用 方法返回这个接口需要的数据
之后将返回的数据进行序列化 并将商品的点击数添加到序列化数据中</p>
<pre><code>class GoodsRank(APIView):

    def get(self,request):

        get_res = get_top_n(10)
        res = []

        for item in get_res:
            for k,v in item.items():
                # 序列化
                data = GoodsSer(v).data
                # 将商品点击数附加到数据中
                data['clicks'] = k
                res.append(data)

        return Response(res)

</code></pre><p><strong>到这里就ok了</strong>
<strong>后端的排行榜接口就被构造完成了</strong>
mysql也可以做排行榜 但是当数量达到百万千万级的实话查询的效率就会变得缓慢
用redis或者MongoDB这样的nosql的话效率就大大提高了 这是关系型数据库望尘莫及的</p>

    </div>
    
      
        <div class="pagination">
          <div class="pagination__title">
            <span class="pagination__title-h">Read other posts</span>
            <hr />
          </div>
          <div class="pagination__buttons">
            
            
              <span class="button next">
                <a href="/my_blog/post/two/">
                  <span class="button__text">vue防止用户恶意点击按钮</span>
                  <span class="button__icon">→</span>
                </a>
              </span>
            
          </div>
        </div>
      
    


    
      
        

      
    

    </div>

      </div>

      
        <footer class="footer">
  <div class="footer__inner">
    
      <a href="/my_blog/hello/" class="logo" style="text-decoration: none;">
  
    <span class="logo__mark"><svg xmlns="http://www.w3.org/2000/svg" class="greater-icon" viewBox="0 0 44 44">
  <path fill="none" d="M15 8l14.729 14.382L15 35.367"/>
</svg>
</span>
    <span class="logo__text">Welcome To MyBlog</span>
    <span class="logo__cursor"></span>
  
</a>

      <div class="copyright">
        <span>© 2020 Powered by <a href="https://gohugo.io" target="_blank" rel="noopener">Hugo</a></span>
        <span>Theme created by <a href="https://twitter.com/panr" target="_blank" rel="noopener">panr</a></span>
      </div>
    
  </div>
</footer>

<script src="/my_blog/assets/main.js"></script>
<script src="/my_blog/assets/prism.js"></script>


      
    </div>

    
  </body>
</html>
